#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int n, pre[1005]; // n表示节点数，pre存储前序遍历序列

typedef struct treenode
{
    int data;                      
    struct treenode *left, *right; 
} tree;

int flag = 0; // 用来标记是否是BST或其镜像

// 建立二叉搜索树
void stablish(tree *t, int left, int right, int place)
{
    if (left > right) // 如果无效，直接返回
    {
        return;
    }

    if (left == right) // 如果只有一个节点
    {
        if (pre[left] < t->data) // 如果该节点值小于当前节点值，加入左子树
        {
            tree *newnodel = (tree *)malloc(sizeof(tree)); 
            newnodel->data = pre[left];
            newnodel->left = NULL;
            newnodel->right = NULL;
            t->left = newnodel;
            return;
        }
        else // 否则加入右子树
        {
            tree *newnoder = (tree *)malloc(sizeof(tree));
            newnoder->data = pre[right];
            newnoder->left = NULL;
            newnoder->right = NULL;
            t->right = newnoder;
            return;
        }
    }

    int r = -1;
    // 查找第一个大于当前节点的值，作为右子树的根节点
    for (int i = left; i <= right; i++)
    {
        if (r == -1 && pre[i] >= t->data) // 找到第一个大于等于当前节点的节点
        {
            r = i; // 将该节点位置作为右子树的起点
        }
        // 如果在右子树部分又出现比当前节点小的节点，则不满足BST
        if (r != -1 && pre[i] < t->data)
        {
            flag = 1; 
            return;
        }
    }

    if (r != -1) // 找到右子树节点
    {
        tree *newnoder = (tree *)malloc(sizeof(tree)); 
        newnoder->data = pre[r];
        newnoder->left = NULL;
        newnoder->right = NULL;
        t->right = newnoder;
        stablish(newnoder, r + 1, right, r); // 递归构建右子树
        if (r != left)
        {                                                  // 如果有左子树
            tree *newnodel = (tree *)malloc(sizeof(tree)); // 创建左子树节点
            newnodel->data = pre[left];
            newnodel->left = NULL;
            newnodel->right = NULL;
            t->left = newnodel;
            stablish(newnodel, left + 1, r - 1, left); // 递归构建左子树
        }
    }

    if (r == -1) // 如果没有找到右子树，则剩下的节点都是左子树
    {
        tree *newnodel = (tree *)malloc(sizeof(tree)); // 创建左子树节点
        newnodel->data = pre[left];
        newnodel->left = NULL;
        newnodel->right = NULL;
        t->left = newnodel;
        stablish(newnodel, left + 1, right, left); // 递归构建左子树
    }
}

// 建立镜像的二叉搜索树
void stablish_mirror(tree *t, int left, int right, int place)
{
    if (left > right) // 无效，直接返回
    {
        return;
    }

    if (left == right) // 如果只有一个节点
    {
        if (pre[left] >= t->data) // 如果该节点值大于等于当前节点，加入左子树
        {
            tree *newnodel = (tree *)malloc(sizeof(tree)); 
            newnodel->data = pre[left];
            newnodel->left = NULL;
            newnodel->right = NULL;
            t->left = newnodel;
            return;
        }
        else // 否则加入右子树
        {
            tree *newnoder = (tree *)malloc(sizeof(tree)); 
            newnoder->data = pre[right];
            newnoder->left = NULL;
            newnoder->right = NULL;
            t->right = newnoder;
            return;
        }
    }

    int r = -1;
    // 查找第一个小于当前节点的值，作为右子树的根节点
    for (int i = left; i <= right; i++)
    {
        if (r == -1 && pre[i] < t->data) 
        {
            r = i; // 记录该节点位置作为右子树的起点
        }
        // 如果在右子树部分又出现比当前节点大的节点，则不满足镜像BST
        if (r != -1 && pre[i] >= t->data)
        {
            flag = 1; // 标记为不合法
            return;
        }
    }

    if (r != -1) // 找到右子树节点
    {
        tree *newnoder = (tree *)malloc(sizeof(tree)); 
        newnoder->data = pre[r];
        newnoder->left = NULL;
        newnoder->right = NULL;
        t->right = newnoder;
        stablish_mirror(newnoder, r + 1, right, r); // 递归构建右子树
        if (r != left)
        {                                                  // 如果有左子树
            tree *newnodel = (tree *)malloc(sizeof(tree)); // 创建左子树节点
            newnodel->data = pre[left];
            newnodel->left = NULL;
            newnodel->right = NULL;
            t->left = newnodel;
            stablish_mirror(newnodel, left + 1, r - 1, left); // 递归构建左子树
        }
    }

    if (r == -1) // 如果没有找到右子树，则剩下的节点都是左子树
    {
        tree *newnodel = (tree *)malloc(sizeof(tree)); // 创建左子树节点
        newnodel->data = pre[left];
        newnodel->left = NULL;
        newnodel->right = NULL;
        t->left = newnodel;
        stablish_mirror(newnodel, left + 1, right, left); // 递归构建左子树
    }
}

int place = 0, print[1005]; // 存储树的后序遍历结果

// 打印树的后序遍历
void print_tree(tree *node)
{
    if (node->left != NULL)
    {
        print_tree(node->left); 
    }
    if (node->right != NULL) 
    {
        print_tree(node->right);
    }
    print[place++] = node->data; // 将当前节点数据加入打印数组
}

int main()
{
    // 输入节点数并读取前序遍历序列
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &pre[i]);
    }

    // 创建根节点
    tree *t = (tree *)malloc(sizeof(tree));
    t->data = pre[0];
    t->left = NULL;
    t->right = NULL;

    // 建立二叉搜索树
    stablish(t, 1, n - 1, 0);

    // 如果普通树不合法，再尝试建立镜像树
    if (flag == 1)
    {
        flag = 0;
        stablish_mirror(t, 1, n - 1, 0);
    }

    if (flag == 0)
    {
        printf("YES\n");
        print_tree(t);                       // 打印后序遍历
        for (int i = 0; i <= place - 2; i++) // 输出后序遍历的前部分
        {
            printf("%d ", print[i]);
        }
        printf("%d", print[place - 1]); // 输出最后一个数字
    }
    else
    {
        printf("NO"); 
    }
}